package com.wy.w_ui.banner.core;

import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Scroller;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.ViewPager;

import com.wy.w_ui.banner.adapter.WBannerAdapter;
import com.wy.w_ui.banner.scroller.WBannerScroller;

import java.lang.reflect.Field;


/**
 * 自动翻页ViewPager
 */
public class WViewPager extends ViewPager {

    private int mIntervalTime;//滚动时间间隔
    private boolean mAutoPlay = true;//是否自动滚动
    private boolean isLayout;//是否调用了 layout 的标志位

    //TODO  Handler 使用
    //private Handler handler = new Handler();//已被弃用
    private Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    };

    private Runnable mRunnable = new Runnable() {
        @Override
        public void run() {
            setNext();
            mHandler.postDelayed(this, mIntervalTime);
        }
    };


    public WViewPager(@NonNull Context context) {
        super(context);
    }

    public WViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }


    /**
     * 设置间隔时间
     *
     * @param mIntervalTime 翻页间隔时间
     */
    public void setIntervalTime(int mIntervalTime) {
        this.mIntervalTime = mIntervalTime;
    }

    /**
     * 设置是否自动滚动
     *
     * @param autoPlay 是否自动滚动
     */
    public void setAutoPlay(boolean autoPlay) {
        this.mAutoPlay = autoPlay;
        if (!mAutoPlay) {
            mHandler.removeCallbacks(mRunnable);
        }
    }

    /**
     * 开始自动播放
     */
    public void startLooper() {
        mHandler.removeCallbacksAndMessages(null);
        if (mAutoPlay) {
            mHandler.postDelayed(mRunnable, mIntervalTime);
        }
    }

    /**
     * 停止自动播放
     */
    public void stopLooper() {
        mHandler.removeCallbacksAndMessages(null);
    }

    /**
     * 设置手指触摸的时候不进行自动滚动
     *
     * @param event
     * @return
     */
    @Override
    public boolean onTrackballEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL://TODO ACTION_CANCEL or 事件传递
                startLooper();
                break;
            default:
                stopLooper();
                break;
        }
        return super.onTrackballEvent(event);
    }

    /**
     * 在 ViewPager 还没有绘制,完成测量的时候 isLayout 设置为 true
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        isLayout = true;
    }

    /**
     * ViewPager 嵌套 RecyclerView Bug
     *
     * @1 RecyclerView 滚动上去,直至 ViewPager 不可见,再滚动下来, ViewPager 下一次切换没有动画
     * @2 当 ViewPager 滚动一半的时候,RecyclerView 滚动上去,再滚动下来,ViewPager 会卡在一半
     * <p>
     * <p>
     * @1原因: ViewPager.setCurrentItemInternal(); if (mFirstLayout) 当第一次 FirstLayout 的时候,
     * 会直接切换 item,执行 dispatchOnPageSelected(),否则会走 scrollToItem(),里面再执行 dispatchOnPageSelected()
     * RecyclerView 在 item 回收再复用的时候会执行 onAttachedToWindow, ViewPager 在 onAttachedToWindow() 方法内把 mFirstLayout 设置为了 true
     * @1解决办法 重写 onAttachedToWindow() 如果已经 layout 过了,利用反射修改 mFirstLayout 设置为 false
     * <p>
     * <p>
     * @2原因: 当 RecyclerView 里面的 ViewPager 被回收的时候会调用 ViewPager 里面的 onDetachedFromWindow() 方法,
     * onDetachedFromWindow() 会执行 removeCallbacks(mEndScrollRunnable); mScroller.abortAnimation();
     * 清除事件和终止动画,导致卡在一半
     * @2解决办法: 重写 onDetachedFromWindow(); 判断 Activity 是否是 isFinishing 状态,如果是正常执行,不是只执行 stop();
     * <p>
     * <p>
     * 当此view附加到窗体上时调用该方法。在这时，view有了一个用于显示的Surface，将开始绘制。注意，此方法要保证在调用onDraw(Canvas) 之前调用，
     * 但可能在调用 onDraw(Canvas) 之前的任何时刻，包括调用 onMeasure(int, int) 之前或之后。
     * 看得出次方法在onDraw方法之前调用，也就是view还没有画出来的时候，可以在此方法中去执行一些初始化的操作，
     * google的AlarmClock动态时钟View就是在这个方法中进行广播的注册
     */
    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (isLayout && getAdapter() != null && getAdapter().getCount() > 0) {
            try {
                Field firstLayout = ViewPager.class.getDeclaredField("mFirstLayout");
                firstLayout.setAccessible(true);
                firstLayout.set(WViewPager.this, false);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        startLooper();
    }

    @Override
    protected void onDetachedFromWindow() {
        if (((Activity) getContext()).isFinishing()) {
            super.onDetachedFromWindow();
        }
        stopLooper();
    }


    /**
     * 设置下一个要滚动的 item
     *
     * @return 下一个要显示的 item 的 position
     */
    private int setNext() {
        int nextPosition = -1;
        if (getAdapter() == null || getAdapter().getCount() <= 1) {
            stopLooper();
            return nextPosition;
        }

        nextPosition = getCurrentItem() + 1;
        //下一个 position 大于 adapter view 的最大数量,从新开始
        if (nextPosition > getAdapter().getCount()) {
            // 获取第一个 item 的索引
            nextPosition = ((WBannerAdapter)getAdapter()).getFirstItem();
        }

        setCurrentItem(nextPosition);
        return nextPosition;
    }

    /**
     * 设置滑动速度
     * @param duration duration
     */
    public void setScroller(int  duration){
        try {
            Field field = ViewPager.class.getDeclaredField("mScroller");
            field.setAccessible(true);
            field.set(field,new WBannerScroller(getContext(),duration));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
